﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EFDataModel;

namespace TimeManagement
{
    public class TimeFunctions
    {
        /// <summary>
        /// Ermitteln die Differenz zwischen Start und endezeit/Datum in Minuten
        /// </summary>
        /// <param name="startDate">Der Startzeitpunkt</param>
        /// <param name="endDate">Der Endzeitpunkt</param>
        /// <returns>Differenz in Minuten</returns>
        public static int DurationInMinutes(DateTime startDate, DateTime endDate)
        {
            TimeSpan timeStart = new TimeSpan(0, startDate.Hour, startDate.Minute, 0);
            TimeSpan timeEnd = new TimeSpan(0, endDate.Hour, endDate.Minute, 0);
            return (int)(timeEnd.TotalMinutes - timeStart.TotalMinutes);
        }

        /// <summary>
        /// Anhand des Settings ermitteln wieviel Stunden jemand pro Tag arbeiten muss.
        /// </summary>
        /// <param name="setting">WorktimeSetting zum Berechnen der täglichen Arbeitszeit.</param>
        /// <returns>Anzahl der Täglichen Arbeitszeit in Minuten</returns>
        public static int DailyWorktimeInMinutes(EFWorktimeSetting setting)
        {
            int workDays = 0;
            //Erst ermitteln wieviele Arbeitstage Pro Woche anstehen.
            workDays += setting.WorkingDays.Mon ? 1 : 0;
            workDays += setting.WorkingDays.Tue ? 1 : 0;
            workDays += setting.WorkingDays.Wed ? 1 : 0;
            workDays += setting.WorkingDays.Thu ? 1 : 0;
            workDays += setting.WorkingDays.Fri ? 1 : 0;
            workDays += setting.WorkingDays.Sat ? 1 : 0;
            workDays += setting.WorkingDays.Sun ? 1 : 0;

            //Anzahl der Minuten ausrechnen die man Pro Woche arbeiten muss.
            double workingMinutes = setting.WorkingHours * 60;
            if (workingMinutes > 0)
            {
                //Die tägliche arbeitzeit ergibt sich aus der Wöchentlichen Arbeitszeit / Anzahl der Arbeitstage
                return (int)workingMinutes / workDays;
            }

            return 0;
        }

        /// <summary>
        /// Anhand des Settings ermitteln welche Tage gearbeitet werden sollen und als Bitmaske zurückgeben
        /// </summary>
        /// <param name="setting">WorktimeSetting zum Bitweise berechnen der passenden Arbeitstage.</param>
        /// <returns>Anzahl der Täglichen Arbeitszeit in Minuten</returns>
        public static EFWorkingDays WorkingDays(EFWorktimeSetting setting)
        {
            EFWorkingDays days = EFWorkingDays.None;
            //Bittweise ermitteln welche Tage gesetzt werden sollen
            if (setting.WorkingDays.Mon) days |= EFWorkingDays.Mon;
            if (setting.WorkingDays.Tue) days |= EFWorkingDays.Tue;
            if (setting.WorkingDays.Wed) days |= EFWorkingDays.Wed;
            if (setting.WorkingDays.Thu) days |= EFWorkingDays.Thu;
            if (setting.WorkingDays.Fri) days |= EFWorkingDays.Fri;
            if (setting.WorkingDays.Sat) days |= EFWorkingDays.Sat;
            if (setting.WorkingDays.Sun) days |= EFWorkingDays.Sun;

            return days;
        }

        /// <summary>
        /// Für das übergebene Datum ermitteln um welchen WorkingDay es sich handelt.
        /// </summary>
        /// <param name="date">Das Datum für das der Eintrag ermitteln werden soll</param>
        public static EFWorkingDays GetWorkingDay(DateTime date)
        {
            switch (date.DayOfWeek)
            {
                case DayOfWeek.Sunday:
                    return EFWorkingDays.Sun;

                case DayOfWeek.Saturday:
                    return EFWorkingDays.Sat;

                case DayOfWeek.Friday:
                    return EFWorkingDays.Fri;

                case DayOfWeek.Thursday:
                    return EFWorkingDays.Thu;

                case DayOfWeek.Wednesday:
                    return EFWorkingDays.Wed;

                case DayOfWeek.Tuesday:
                    return EFWorkingDays.Tue;

                case DayOfWeek.Monday:
                    return EFWorkingDays.Mon;
            }

            return EFWorkingDays.Fri;
        }
    }
}
